<template>
  <div id="app" :class="{ 'light-theme': !isDarkTheme, 'dark-theme': isDarkTheme }">
    <el-config-provider :locale="locale" :size="size">
      <el-container class="main-container">
        <!-- 头部 -->
        <el-header height="70px" class="app-header">
          <div class="header-content">
            <h1 class="app-title">
              <el-icon class="app-icon">
                <Upload />
              </el-icon>
              文件上传管理
            </h1>
            <!-- 主题切换按钮 -->
            <el-button @click="toggleTheme" :icon="isDarkTheme ? Moon : Sunny" circle class="theme-toggle-btn"
              :title="isDarkTheme ? '切换到浅色主题' : '切换到深色主题'" />
          </div>
        </el-header>

        <!-- 主体 -->
        <el-main class="app-main">
          <!-- 操作栏 -->
          <div class="action-bar">
            <div class="buttons">
              <el-button type="primary" size="default" :icon="Upload" @click="showUploadDialog = true"
                :disabled="uploading || isNetworkError || isMaintenanceMode">
                上传
              </el-button>
              <el-button size="default" :icon="FolderAdd" @click="createFolder"
                :disabled="creatingFolder || isNetworkError || isMaintenanceMode">
                新建文件夹
              </el-button>
              <!-- 桌面端批量操作按钮 -->
              <template v-if="!isMobile">
                <el-button size="default" :icon="Download"
                  :disabled="selectedItems.length === 0 || !hasFilesInSelection || downloading || isNetworkError || isMaintenanceMode"
                  @click="handleBatchDownload">
                  下载选中
                </el-button>
                <el-button size="default" :icon="Delete" type="danger"
                  :disabled="selectedItems.length === 0 || deleting || isNetworkError || isMaintenanceMode"
                  @click="handleBatchDelete">
                  删除选中
                </el-button>
              </template>
              <!-- 全选按钮 - 桌面端 -->
              <template v-if="!isMobile">
                <el-dropdown trigger="click" @command="handleSelectAllCommand">
                  <el-button size="default" :icon="Check"
                    :disabled="filteredFileList.length === 0 || isNetworkError || isMaintenanceMode">
                    全选 <el-icon class="el-icon--right"><arrow-down /></el-icon>
                  </el-button>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item command="download"
                        :disabled="!hasFilesInList || downloading || isNetworkError || isMaintenanceMode">全选下载</el-dropdown-item>
                      <el-dropdown-item command="delete"
                        :disabled="deleting || isNetworkError || isMaintenanceMode">全选删除</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </template>
              <!-- 全选按钮 - 移动端简化版 -->
              <el-button v-else size="default" :icon="Check" @click="handleMobileSelectAll"
                :disabled="filteredFileList.length === 0 || isNetworkError || isMaintenanceMode">
                全选
              </el-button>
            </div>

            <!-- 搜索框 -->
            <el-input v-model="searchKeyword" placeholder="搜索文件名..." :prefix-icon="Search"
              style="flex-grow: 1; max-width: none;" clearable :disabled="isNetworkError || isMaintenanceMode" />
          </div>

          <!-- 移动端专用批量操作栏 -->
          <div class="mobile-batch-bar" v-if="isMobile && selectedItems.length > 0">
            <el-tag size="small" type="info">{{ selectedItems.length }} 项已选择</el-tag>
            <el-button-group>
              <el-button size="small" :icon="Download"
                :disabled="!hasFilesInSelection || downloading || isNetworkError || isMaintenanceMode"
                @click="handleBatchDownload"></el-button>
              <el-button size="small" :icon="Delete" type="danger"
                :disabled="deleting || isNetworkError || isMaintenanceMode" @click="handleBatchDelete"></el-button>
              <el-button size="small" :icon="Close" @click="clearSelection"></el-button>
            </el-button-group>
          </div>

          <!-- 面包屑 -->
          <el-breadcrumb :separator-icon="ArrowRight" class="breadcrumb">
            <el-breadcrumb-item @click="navigateTo('root')">
              <el-icon>
                <House />
              </el-icon> 根目录
            </el-breadcrumb-item>
            <el-breadcrumb-item v-for="dir in breadcrumb" :key="dir.id" @click="navigateTo(dir.id)">
              {{ dir.name }}
            </el-breadcrumb-item>
          </el-breadcrumb>

          <!-- 文件列表 -->
          <el-table :data="filteredFileList" stripe border max-height="580" class="file-table"
            :empty-text="getEmptyText()" v-loading="loading" @sort-change="handleSortChange"
            :default-sort="{ prop: 'createdAt', order: 'descending' }" @selection-change="handleSelectionChange"
            ref="fileTableRef" :show-header="!isVerySmallScreen">
            <!-- 多选框 -->
            <el-table-column type="selection" width="45" align="center"></el-table-column>

            <el-table-column prop="name" label="文件名" min-width="250" sortable>
              <template #default="scope">
                <el-tooltip :content="scope.row.name" placement="top" effect="light">
                  <div class="file-cell">
                    <el-icon :style="{ color: getIconColor(scope.row) }" class="file-icon">
                      <component :is="getIconComponent(scope.row)" />
                    </el-icon>
                    <span class="file-name">{{ scope.row.name }}</span>
                  </div>
                </el-tooltip>
              </template>
            </el-table-column>

            <!-- MD5 列 -->
            <el-table-column prop="md5" label="MD5" min-width="150" sortable>
              <template #default="scope">
                <span v-if="scope.row.type === 'file'">{{ scope.row.md5 || 'N/A' }}</span>
                <span v-else>--</span>
              </template>
            </el-table-column>

            <el-table-column v-if="!isVerySmallScreen" prop="size" label="大小" width="110" sortable>
              <template #default="scope">
                {{ scope.row.type === 'folder' ? '--' : formatSize(scope.row.size) }}
              </template>
            </el-table-column>

            <el-table-column v-if="!isVerySmallScreen" prop="createdAt" label="创建时间" width="110" sortable>
              <template #default="scope">
                {{ new Date(scope.row.createdAt).toLocaleDateString() }}
              </template>
            </el-table-column>

            <!-- 修改后的操作列 -->
            <el-table-column label="操作" width="250" align="center" fixed="right">
              <template #default="scope">
                <div class="action-buttons">
                  <el-tooltip v-if="scope.row.type === 'file'" content="预览" placement="top">
                    <el-button class="action-btn action-btn--preview" @click="previewFile(scope.row)"
                      :disabled="previewing || isNetworkError || isMaintenanceMode">
                      <el-icon>
                        <View />
                      </el-icon>
                    </el-button>
                  </el-tooltip>
                  <el-tooltip v-if="scope.row.type === 'file'" content="下载" placement="top">
                    <el-button class="action-btn action-btn--download" @click="downloadFile(scope.row)"
                      :disabled="downloading || isNetworkError || isMaintenanceMode">
                      <el-icon>
                        <Download />
                      </el-icon>
                    </el-button>
                  </el-tooltip>
                  <el-tooltip v-else content="进入文件夹" placement="top">
                    <el-button class="action-btn action-btn--enter-folder" @click="enterFolder(scope.row)"
                      :disabled="navigating || isNetworkError || isMaintenanceMode">
                      <el-icon>
                        <FolderOpened />
                      </el-icon>
                    </el-button>
                  </el-tooltip>
                  <!-- 新增的重命名按钮 -->
                  <el-tooltip content="重命名" placement="top">
                    <el-button class="action-btn action-btn--rename" @click="renameFile(scope.row)"
                      :disabled="renaming || isNetworkError || isMaintenanceMode">
                      <el-icon>
                        <Edit />
                      </el-icon>
                    </el-button>
                  </el-tooltip>
                  <el-tooltip content="删除" placement="top">
                    <el-button class="action-btn action-btn--delete" @click="deleteFile(scope.row)"
                      :disabled="deleting || isNetworkError || isMaintenanceMode">
                      <el-icon>
                        <Delete />
                      </el-icon>
                    </el-button>
                  </el-tooltip>
                </div>
              </template>
            </el-table-column>
          </el-table>
        </el-main>
      </el-container>

      <!-- 上传弹窗 -->
      <UploadDialog v-model:visible="showUploadDialog" :current-parent="currentParent" @upload-success="fetchFiles" />

      <!-- 预览弹窗 -->
      <PreviewDialog v-model:visible="previewDialogVisible" :file-data="previewFileData" @close="handlePreviewClose"
        @download="downloadFile" />

      <!-- 网络错误提示 -->
      <el-dialog v-model="isNetworkError" title="网络连接问题" width="30%" center>
        <span>无法连接到服务器，请检查您的网络连接或稍后再试。</span>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="retryFetch">重试</el-button>
          </span>
        </template>
      </el-dialog>

      <!-- 维护模式提示 -->
      <el-dialog v-model="isMaintenanceMode" title="系统维护中" width="30%" center>
        <span>系统正在进行维护，暂时无法提供服务。请稍后再试。</span>
      </el-dialog>
    </el-config-provider>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, nextTick, onBeforeUnmount } from 'vue'
import { ElMessage, ElMessageBox, ElConfigProvider } from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import {
  Search, Upload, FolderAdd, Download, Delete, Check, Close, ArrowDown, ArrowRight, House, FolderOpened,
  Folder, VideoPlay, Document, Tickets, Present, Box, Picture, Headset, Coffee, Files, DataAnalysis,
  SetUp, Coin, Link, Collection, Star, Edit, View, Sunny, Moon
} from '@element-plus/icons-vue'
import UploadDialog from './components/UploadDialog.vue'
import PreviewDialog from './components/PreviewDialog.vue'
import request from './utils/request'

// 设置 Element Plus 语言
const locale = zhCn

// 响应式数据
const fileList = ref([])
const currentParent = ref('root')
const breadcrumb = ref([])
const showUploadDialog = ref(false)
const loading = ref(false)
const searchKeyword = ref('')
const sortProp = ref('createdAt')
const sortOrder = ref('descending')
const selectedItems = ref([])
const isMobile = ref(false)
const isVerySmallScreen = ref(false)
const fileTableRef = ref(null)

// 新增：预览对话框相关响应式变量
const previewDialogVisible = ref(false)
const previewFileData = ref(null)

// 新增：状态管理，防止并发操作
const uploading = ref(false)
const creatingFolder = ref(false)
const downloading = ref(false)
const deleting = ref(false)
const renaming = ref(false)
const navigating = ref(false)
const previewing = ref(false)

// 新增：网络状态管理
const isNetworkError = ref(false)
const retryTimer = ref(null)

// 新增：维护模式状态
const isMaintenanceMode = ref(false)

// 新增：主题状态
const isDarkTheme = ref(localStorage.getItem('theme') === 'dark' || false)

// 主题切换函数
const toggleTheme = () => {
  isDarkTheme.value = !isDarkTheme.value;
  localStorage.setItem('theme', isDarkTheme.value ? 'dark' : 'light');
  updateTheme();
}

// 更新主题的函数
const updateTheme = () => {
  if (isDarkTheme.value) {
    document.documentElement.classList.add('dark');
    document.body.setAttribute('data-theme', 'dark');
  } else {
    document.documentElement.classList.remove('dark');
    document.body.setAttribute('data-theme', 'light');
  }
}

// 计算属性
const filteredFileList = computed(() => {
  let list = [...fileList.value]

  if (searchKeyword.value) {
    const keyword = searchKeyword.value.toLowerCase()
    list = list.filter(item =>
      item.name.toLowerCase().includes(keyword)
    )
  }

  if (sortProp.value && sortOrder.value) {
    const prop = sortProp.value
    const order = sortOrder.value === 'ascending' ? 1 : -1

    list = list.sort((a, b) => {
      let valA = a[prop]
      let valB = b[prop]

      if (prop === 'size') {
        valA = a.type === 'folder' ? -1 : a.size
        valB = b.type === 'folder' ? -1 : b.size
      } else if (prop === 'createdAt') {
        valA = new Date(valA)
        valB = new Date(valB)
      } else if (prop === 'md5') {
        valA = valA || '';
        valB = valB || '';
      }

      if (valA < valB) return -1 * order
      if (valA > valB) return 1 * order
      return 0
    })
  }

  return list
})

const hasFilesInSelection = computed(() => {
  return selectedItems.value.some(item => item.type === 'file');
})

const hasFilesInList = computed(() => {
  return filteredFileList.value.some(item => item.type === 'file');
})

// 方法
const checkScreenSize = () => {
  isMobile.value = window.innerWidth <= 768;
  isVerySmallScreen.value = window.innerWidth <= 480;
}

const getEmptyText = () => {
  if (loading.value) return '加载中...';
  if (isNetworkError.value) return '网络错误，请检查连接后重试。';
  if (isMaintenanceMode.value) return '系统维护中，请稍后再试。';
  return '暂无文件';
}

const fetchFiles = async () => {
  if (loading.value) return; // 防止重复请求
  loading.value = true;
  isNetworkError.value = false; // 重置网络错误状态
  try {
    const res = await request.get('/files', {
      params: { parent: currentParent.value }
    });
    // 检查响应数据结构
    if (res && typeof res === 'object' && !Array.isArray(res)) {
      if (res.maintenance) {
        isMaintenanceMode.value = true;
        fileList.value = [];
        return;
      }
    }
    fileList.value = Array.isArray(res) ? res : [];
    // 清除选择
    nextTick(() => {
      if (fileTableRef.value) {
        fileTableRef.value.clearSelection();
      }
    });
  } catch (error) {
    console.error('获取文件列表失败:', error);
    // 检查是否为网络错误
    if (error.code === 'NETWORK_ERROR' || !error.response) {
      isNetworkError.value = true;
      fileList.value = []; // 清空列表以显示错误信息
    } else {
      ElMessage({
        message: error.response?.data?.error || '获取文件列表失败，请稍后重试',
        type: 'error',
        duration: 3000
      });
      fileList.value = []; // 清空列表
    }
  } finally {
    loading.value = false;
  }
};

// 重试获取文件
const retryFetch = () => {
  clearTimeout(retryTimer.value);
  retryTimer.value = setTimeout(() => {
    fetchFiles();
  }, 500); // 防抖
};

const formatSize = (bytes) => {
  if (bytes === 0) return '0 B';
  if (isNaN(bytes) || bytes < 0) return 'N/A';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

const previewFile = async (file) => {
  if (previewing.value) return;
  previewing.value = true;
  try {
    previewFileData.value = file;
    previewDialogVisible.value = true;
  } catch (error) {
    console.error("预览文件失败:", error);
    ElMessage.error('预览文件失败');
  } finally {
    previewing.value = false;
  }
};

const handlePreviewClose = () => {
  // 关闭预览时清理文本内容
};

const downloadFile = async (file) => {
  if (downloading.value) return;
  downloading.value = true;
  try {
    const link = document.createElement('a');
    link.href = `/api/files/${file.id}/download`;
    link.download = file.name;
    link.style.display = 'none';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  } catch (error) {
    console.error("下载文件失败:", error);
    ElMessage.error('下载文件失败');
  } finally {
    downloading.value = false;
  }
};

const renameFile = async (file) => {
  if (renaming.value) return;
  renaming.value = true;
  try {
    const { value } = await ElMessageBox.prompt('请输入新的文件名', '重命名', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      inputPlaceholder: '请输入新名称',
      inputValue: file.name,
      inputValidator: (val) => {
        const trimmedVal = val?.trim();
        if (!trimmedVal) return '名称不能为空';
        if (trimmedVal.includes('/') || trimmedVal.includes('\\')) return '名称不能包含 / 或 \\';
        return true;
      },
      inputErrorMessage: '请输入有效的文件名'
    });

    const newName = value.trim();
    if (newName === file.name) {
      ElMessage.info('文件名未改变');
      return;
    }

    const res = await request.put(`/files/${file.id}/rename`, { newName });
    ElMessage.success(res.message || `"${file.name}" 已重命名为 "${newName}"`);
    await fetchFiles();
  } catch (error) {
    if (error !== 'cancel') {
      console.error("Rename error:", error);
      const errorMsg = error.response?.data?.error || '重命名失败';
      ElMessage.error(errorMsg);
    }
  } finally {
    renaming.value = false;
  }
};

const deleteFile = async (file) => {
  if (deleting.value) return;
  deleting.value = true;
  try {
    await ElMessageBox.confirm(`确定要删除 "${file.name}" 吗？`, '删除确认', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning',
      confirmButtonClass: 'el-button--danger'
    });
    await request.delete(`/files/${file.id}`);
    ElMessage.success(`"${file.name}" 已删除`);
    await fetchFiles();
  } catch (error) {
    if (error !== 'cancel') {
      console.error("删除文件失败:", error);
      ElMessage.error(error.response?.data?.error || '删除失败');
    }
  } finally {
    deleting.value = false;
  }
};

const enterFolder = async (folder) => {
  if (navigating.value) return;
  navigating.value = true;
  try {
    breadcrumb.value.push({ id: folder.id, name: folder.name });
    currentParent.value = folder.id;
    await fetchFiles();
  } catch (error) {
    console.error("进入文件夹失败:", error);
    ElMessage.error('进入文件夹失败');
    // 回滚状态
    breadcrumb.value.pop();
  } finally {
    navigating.value = false;
  }
};

const navigateTo = async (parentId) => {
  if (navigating.value) return;
  navigating.value = true;
  try {
    if (parentId === 'root') {
      breadcrumb.value = [];
    } else {
      const index = breadcrumb.value.findIndex(dir => dir.id === parentId);
      if (index > -1) {
        breadcrumb.value = breadcrumb.value.slice(0, index + 1);
      }
    }
    currentParent.value = parentId;
    await fetchFiles();
  } catch (error) {
    console.error("导航失败:", error);
    ElMessage.error('导航失败');
  } finally {
    navigating.value = false;
  }
};

const createFolder = async () => {
  if (creatingFolder.value) return;
  creatingFolder.value = true;
  try {
    const { value } = await ElMessageBox.prompt('请输入文件夹名称', '新建文件夹', {
      confirmButtonText: '创建',
      cancelButtonText: '取消',
      inputPlaceholder: '请输入名称',
      inputValue: '',
      inputValidator: (val) => !!val?.trim(),
      inputErrorMessage: '名称不能为空'
    });

    const name = value.trim();
    await request.post('/folders', { name, parent: currentParent.value });
    ElMessage.success(`已创建文件夹：${name}`);
    await fetchFiles();
  } catch (error) {
    if (error !== 'cancel') {
      console.error("创建文件夹失败:", error);
      ElMessage.error(error.response?.data?.error || '创建失败，请重试');
    }
  } finally {
    creatingFolder.value = false;
  }
};

const handleSortChange = ({ column, prop, order }) => {
  sortProp.value = prop;
  sortOrder.value = order || 'ascending';
};

const handleSelectionChange = (selection) => {
  selectedItems.value = selection;
};

const clearSelection = () => {
  if (fileTableRef.value) {
    fileTableRef.value.clearSelection();
  }
};

const handleBatchDownload = async () => {
  if (downloading.value || selectedItems.value.length === 0) return;
  downloading.value = true;
  const filesToDownload = selectedItems.value.filter(item => item.type === 'file');

  if (filesToDownload.length === 0) {
    ElMessage.warning('请选择至少一个文件进行下载');
    downloading.value = false;
    return;
  }

  try {
    filesToDownload.forEach(file => {
      setTimeout(() => {
        downloadFile(file);
      }, 100);
    });

    ElMessage.success(`开始下载 ${filesToDownload.length} 个文件`);
    if (isMobile.value) {
      clearSelection();
    }
  } catch (error) {
    console.error("批量下载失败:", error);
    ElMessage.error('批量下载失败');
  } finally {
    downloading.value = false;
  }
};

const handleBatchDelete = async () => {
  if (deleting.value || selectedItems.value.length === 0) return;
  deleting.value = true;

  try {
    await ElMessageBox.confirm(`确定要删除选中的 ${selectedItems.value.length} 项吗？`, '批量删除确认', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning',
      confirmButtonClass: 'el-button--danger'
    });

    const deletePromises = selectedItems.value.map(item =>
      request.delete(`/files/${item.id}`)
    );

    await Promise.all(deletePromises);

    ElMessage.success(`已删除 ${selectedItems.value.length} 项`);
    await fetchFiles();
    if (isMobile.value) {
      clearSelection();
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error("批量删除失败:", error);
      ElMessage.error(error.response?.data?.error || '批量删除失败');
    }
  } finally {
    deleting.value = false;
  }
};

const getIconComponent = (row) => {
  if (row.type === 'folder') {
    return Folder;
  }

  const ext = (row.name || '').split('.').pop().toLowerCase();
  const icons = {
    'mp4': VideoPlay, 'avi': VideoPlay, 'mkv': VideoPlay, 'mov': VideoPlay,
    'wmv': VideoPlay, 'flv': VideoPlay, 'webm': VideoPlay, 'm4v': VideoPlay,
    '3gp': VideoPlay, 'ogv': VideoPlay,

    'pdf': Document, 'doc': Document, 'docx': Document, 'txt': Document,
    'md': Document, 'rtf': Document, 'odt': Document, 'pages': Document,

    'xls': Tickets, 'xlsx': Tickets, 'csv': Tickets, 'ods': Tickets,

    'ppt': Present, 'pptx': Present, 'odp': Present, 'key': Present,

    'zip': Box, 'rar': Box, '7z': Box, 'tar': Box,
    'gz': Box, 'bz2': Box, 'xz': Box,

    'jpg': Picture, 'jpeg': Picture, 'png': Picture, 'gif': Picture,
    'bmp': Picture, 'webp': Picture, 'svg': Picture, 'tiff': Picture,
    'ico': Picture, 'psd': Picture,

    'mp3': Headset, 'wav': Headset, 'flac': Headset, 'aac': Headset,
    'ogg': Headset, 'wma': Headset, 'm4a': Headset, 'aiff': Headset,

    'js': Coffee, 'ts': Coffee, 'jsx': Coffee, 'tsx': Coffee,
    'java': Coffee, 'py': Coffee, 'cpp': Coffee, 'c': Coffee,
    'cs': Coffee, 'go': Coffee, 'rb': Coffee, 'php': Coffee,
    'html': Files, 'css': Files, 'scss': Files, 'less': Files,
    'xml': DataAnalysis, 'json': DataAnalysis, 'yaml': DataAnalysis, 'yml': DataAnalysis,

    'exe': SetUp, 'msi': SetUp, 'app': SetUp, 'dmg': SetUp,
    'deb': SetUp, 'rpm': SetUp, 'apk': SetUp,

    'sql': DataAnalysis, 'db': DataAnalysis, 'sqlite': DataAnalysis, 'mdb': DataAnalysis,

    'ttf': Star, 'otf': Star, 'woff': Star, 'woff2': Star,

    'iso': Coin, 'dmg': Coin,
    'lnk': Link, 'url': Link,
    'log': Collection,
  };

  return icons[ext] || Document;
};

const getIconColor = (row) => {
  if (row.type === 'folder') {
    return '#409EFF';
  }

  const ext = (row.name || '').split('.').pop().toLowerCase();
  const colors = {
    'mp4': '#F56C6C', 'avi': '#F56C6C', 'mkv': '#F56C6C', 'mov': '#F56C6C',
    'wmv': '#F78989', 'flv': '#F78989', 'webm': '#F78989',

    'pdf': '#E6A23C',

    'jpg': '#67C23A', 'jpeg': '#67C23A', 'png': '#67C23A', 'gif': '#85CE61',
    'bmp': '#85CE61', 'webp': '#85CE61', 'svg': '#85CE61',

    'mp3': '#909399', 'wav': '#909399', 'flac': '#A8ABB2', 'aac': '#A8ABB2',

    'zip': '#409EFF', 'rar': '#409EFF', '7z': '#79BBFF', 'tar': '#79BBFF',
    'gz': '#79BBFF',

    'doc': '#5e7ce0', 'docx': '#5e7ce0', 'txt': '#5e7ce0', 'md': '#5e7ce0',
    'rtf': '#7693f5', 'odt': '#7693f5',

    'xls': '#67C23A', 'xlsx': '#67C23A', 'csv': '#85CE61', 'ods': '#85CE61',

    'ppt': '#F56C6C', 'pptx': '#F56C6C', 'odp': '#F78989', 'key': '#F78989',

    'js': '#3178c6', 'ts': '#3178c6', 'jsx': '#00d8ff', 'tsx': '#00d8ff',
    'java': '#ed8b00', 'py': '#3572A5', 'cpp': '#f34b7d', 'c': '#555555',
    'html': '#e34c26', 'css': '#563d7c', 'php': '#777bb3', 'go': '#00ADD8',
    'rb': '#cc342d',

    'exe': '#a970ff', 'msi': '#a970ff', 'app': '#a970ff', 'dmg': '#a970ff',

    'sql': '#e38d13', 'db': '#e38d13', 'sqlite': '#e38d13',
  };

  return colors[ext] || '#909399';
};

const handleMobileSelectAll = () => {
  if (selectedItems.value.length === 0) {
    const filesToSelect = filteredFileList.value.filter(item => item.type === 'file');
    if (filesToSelect.length === 0) {
      ElMessage.warning('当前列表中没有可下载的文件');
      return;
    }

    if (fileTableRef.value) {
      fileTableRef.value.clearSelection();
      nextTick(() => {
        filesToSelect.forEach(file => {
          fileTableRef.value.toggleRowSelection(file, true);
        });
      });
    }
  } else {
    handleBatchDownload();
  }
};

const handleSelectAllCommand = (command) => {
  if (command === 'download') {
    selectAllAndDownload();
  } else if (command === 'delete') {
    selectAllAndDelete();
  }
};

const selectAllAndDownload = () => {
  const filesToSelect = filteredFileList.value.filter(item => item.type === 'file');

  if (filesToSelect.length === 0) {
    ElMessage.warning('当前列表中没有可下载的文件');
    return;
  }

  if (fileTableRef.value) {
    fileTableRef.value.clearSelection();
    nextTick(() => {
      filesToSelect.forEach(file => {
        fileTableRef.value.toggleRowSelection(file, true);
      });
      nextTick(() => {
        handleBatchDownload();
      });
    });
  }
};

const selectAllAndDelete = async () => {
  const itemsToDelete = filteredFileList.value;

  if (itemsToDelete.length === 0) {
    ElMessage.warning('当前列表为空');
    return;
  }

  try {
    await ElMessageBox.confirm(`确定要删除当前列表中的全部 ${itemsToDelete.length} 项吗？`, '全选删除确认', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning',
      confirmButtonClass: 'el-button--danger'
    });

    const deletePromises = itemsToDelete.map(item =>
      request.delete(`/files/${item.id}`)
    );

    await Promise.all(deletePromises);

    ElMessage.success(`已删除 ${itemsToDelete.length} 项`);
    await fetchFiles();
  } catch (error) {
    if (error !== 'cancel') {
      console.error("全选删除失败:", error);
      ElMessage.error(error.response?.data?.error || '全选删除失败');
    }
  }
};

// 修复ResizeObserver错误 - 添加防抖
let resizeObserver = null;
let resizeTimeout = null;

const debouncedResizeHandler = () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(() => {
    checkScreenSize();
  }, 16); // 60fps
};

onMounted(() => {
  // 初始化屏幕尺寸
  checkScreenSize();

  // 使用ResizeObserver监听容器尺寸变化
  if (window.ResizeObserver && document.querySelector('.main-container')) {
    resizeObserver = new ResizeObserver(debouncedResizeHandler);
    resizeObserver.observe(document.querySelector('.main-container'));
  } else {
    // Fallback to window resize event
    window.addEventListener('resize', debouncedResizeHandler);
  }

  // 获取文件列表
  fetchFiles();

  // 初始化主题
  updateTheme();
});

onUnmounted(() => {
  // 清理ResizeObserver
  if (resizeObserver) {
    resizeObserver.disconnect();
    resizeObserver = null;
  }

  // 清理window事件监听器
  window.removeEventListener('resize', debouncedResizeHandler);

  // 清理定时器
  clearTimeout(retryTimer.value);
  clearTimeout(resizeTimeout);
});

onBeforeUnmount(() => {
  // 再次确保清理定时器
  clearTimeout(retryTimer.value);
  clearTimeout(resizeTimeout);
});
</script>

<style scoped>
#app {
  font-family: Inter, 'Helvetica Neue', Helvetica, 'PingFang SC',
    'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background: #ffffff;
  min-height: 100vh;
  padding: 20px 0;
  color: #333;
  line-height: 1.6;
}

#app.dark-theme {
  background: #555050;
  color: #409EFF;
}

#app.light-theme {
  background: #f0f2f5;
  color: #333;
}

.main-container {
  min-height: calc(100vh - 70px);
  border: none;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1);
  margin: 10px auto;
  max-width: 1400px;
  background: #ffffff;
  color: #333;
}

.app-header {
  background: linear-gradient(135deg, #409EFF 0%, #3a5af5 100%);
  color: white;
  padding: 0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-content {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  flex: 1;
}

.app-title {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.5px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  text-align: center;
}

.app-icon {
  margin-right: 10px;
  font-size: 24px;
}

.theme-toggle-btn {
  margin-left: 20px;
  background: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: white;
}

.theme-toggle-btn:hover {
  background: rgba(255, 255, 255, 0.3);
}

.app-main {
  padding: 20px;
  background-color: #f8f9fa;
  color: #333;
}

.action-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 20px;
  align-items: center;
}

.buttons {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}

.buttons .el-button {
  padding: 10px 16px;
  font-size: 14px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  background-color: #ffffff;
  border: 1px solid #dcdfe6;
  color: #606266;
}

.buttons .el-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
  background-color: #ecf5ff;
  border-color: #409eff;
}

.buttons .el-button:active {
  transform: translateY(0);
}

.buttons .el-button.is-disabled {
  background-color: #f5f7fa;
  border-color: #e4e7ed;
  color: #c0c4cc;
}

.mobile-batch-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(120deg, #e6f7ff, #d9f2ff);
  border: 1px solid #b7e4ff;
  padding: 12px 16px;
  margin-bottom: 20px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}

.mobile-batch-bar .el-tag {
  margin-right: 12px;
  font-weight: 500;
  background-color: #d9f2ff;
  color: #1890ff;
}

.mobile-batch-bar .el-button-group .el-button {
  padding: 8px;
  margin: 0 2px;
  background-color: #ffffff;
  border: 1px solid #dcdfe6;
  color: #606266;
}

.breadcrumb {
  font-size: 14px;
  color: #606266;
  margin-bottom: 20px;
  padding: 10px 15px;
  background-color: #ffffff;
  border: 1px solid #ebeef5;
}

.breadcrumb :deep(.el-breadcrumb__inner),
.breadcrumb :deep(.el-breadcrumb__inner a) {
  font-weight: normal;
  color: #606266;
  cursor: pointer;
  transition: color 0.2s;
}

.breadcrumb :deep(.el-breadcrumb__inner:hover),
.breadcrumb :deep(.el-breadcrumb__inner a:hover) {
  color: #409eff;
  font-weight: 500;
}

.file-table {
  overflow: hidden;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  background-color: #ffffff;
}

.file-table :deep(.el-table th) {
  background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
  font-weight: 600;
  color: #303133;
  padding: 12px 0;
  border-bottom: 1px solid #ebeef5;
}

.file-table :deep(.el-table__body tr:hover td) {
  background-color: #f5f7fa !important;
}

.file-table :deep(.el-table__body tr td) {
  padding: 12px 0;
  transition: background-color 0.2s;
  font-size: 14px;
  border-bottom: 1px solid #ebeef5;
  color: #606266;
}

.file-cell {
  display: flex;
  align-items: center;
}

.file-icon {
  font-size: 18px;
  margin-right: 10px;
  flex-shrink: 0;
}

.file-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
}

.el-table :deep(.el-table__body-wrapper .el-table__body tr td:nth-child(3)) {
  font-family: 'Courier New', Courier, monospace;
  font-size: 12px;
  color: #909399;
  word-break: break-all;
}

.action-buttons {
  display: flex;
  justify-content: center;
  gap: 6px;
}

.action-btn {
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  color: #ffffff;
  font-size: 16px;
  background: #ffffff;
  border: 1px solid #dcdfe6;
}

.action-btn:hover {
  transform: translateY(-2px) scale(1.05);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.action-btn:active {
  transform: translateY(0) scale(0.98);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.action-btn.is-disabled {
  background: #f5f7fa !important;
  opacity: 0.5;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.action-btn--preview {
  background: linear-gradient(135deg, #409EFF, #3a5af5);
  color: white;
}

.action-btn--preview:hover {
  background: linear-gradient(135deg, #3a5af5, #2a4ae5);
}

.action-btn--download {
  background: linear-gradient(135deg, #67C23A, #5daf2d);
  color: white;
}

.action-btn--download:hover {
  background: linear-gradient(135deg, #5daf2d, #4d9e24);
}

.action-btn--enter-folder {
  background: linear-gradient(135deg, #409EFF, #3a5af5);
  color: white;
}

.action-btn--enter-folder:hover {
  background: linear-gradient(135deg, #3a5af5, #2a4ae5);
}

.action-btn--rename {
  background: linear-gradient(135deg, #E6A23C, #d8962e);
  color: white;
}

.action-btn--rename:hover {
  background: linear-gradient(135deg, #d8962e, #c98a24);
}

.action-btn--delete {
  background: linear-gradient(135deg, #F56C6C, #e75a5a);
  color: white;
}

.action-btn--delete:hover {
  background: linear-gradient(135deg, #e75a5a, #d94848);
}

/* 深色主题样式 */
#app.dark-theme {
  background: #383535;
  color: #409EFF;
}

#app.dark-theme .main-container {
  background: #000000;
  color: #409EFF;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
}

#app.dark-theme .app-header {
  background: linear-gradient(135deg, #000000 0%, #000000 100%);
  color: #409EFF;
  border-bottom: 1px solid #409EFF;
}

#app.dark-theme .app-main {
  background-color: #000000;
  color: #409EFF;
}

#app.dark-theme .buttons .el-button {
  background-color: #000000;
  border: 1px solid #409EFF;
  color: #409EFF;
}

#app.dark-theme .buttons .el-button:hover {
  background-color: #000000;
  border-color: #409EFF;
  color: #FFFFFF;
}

#app.dark-theme .mobile-batch-bar {
  background: linear-gradient(120deg, #000000, #000000);
  border: 1px solid #409EFF;
}

#app.dark-theme .breadcrumb {
  background-color: #000000;
  border: 1px solid #409EFF;
  color: #409EFF;
}

#app.dark-theme .breadcrumb :deep(.el-breadcrumb__inner),
#app.dark-theme .breadcrumb :deep(.el-breadcrumb__inner a) {
  color: #409EFF;
}

#app.dark-theme .breadcrumb :deep(.el-breadcrumb__inner:hover),
#app.dark-theme .breadcrumb :deep(.el-breadcrumb__inner a:hover) {
  color: #409EFF;
}

#app.dark-theme .file-table {
  background-color: #000000;
  color: #409EFF;
}

#app.dark-theme .file-table :deep(.el-table th) {
  background: linear-gradient(180deg, #000000 0%, #000000 100%);
  color: #409EFF;
  border-bottom: 1px solid #409EFF;
}

#app.dark-theme .file-table :deep(.el-table__body tr:hover td) {
  background-color: #000000 !important;
}

#app.dark-theme .file-table :deep(.el-table__body tr td) {
  border-bottom: 1px solid #409EFF;
  color: #409EFF;
}

#app.dark-theme .file-name {
  color: #409EFF;
}

#app.dark-theme .action-btn {
  background: #000000;
  border: 1px solid #409EFF;
  color: #409EFF;
}

#app.dark-theme .action-btn:hover {
  background: #409EFF;
  color: #000000;
}

#app.dark-theme .action-btn.is-disabled {
  background: #000000 !important;
  opacity: 0.5;
  color: #409EFF;
}

@media (max-width: 768px) {
  #app {
    padding: 10px 0;
  }

  .main-container {
    margin: 5px auto;
  }

  .app-main {
    padding: 15px;
  }

  .action-bar {
    flex-direction: column;
    align-items: stretch;
  }

  .buttons {
    justify-content: center;
  }

  .buttons .el-button {
    flex: 1;
    padding: 9px 14px;
    font-size: 13px;
  }

  .app-title {
    font-size: 20px;
    justify-content: flex-start;
    text-align: left;
  }

  .app-icon {
    font-size: 20px;
    margin-right: 8px;
  }

  .theme-toggle-btn {
    margin-left: 0;
  }

  .breadcrumb {
    text-align: center;
    font-size: 13px;
    padding: 8px 12px;
  }

  .file-table :deep(.el-table__body tr td) {
    padding: 10px 0;
    font-size: 13px;
  }

  .file-icon {
    font-size: 16px;
    margin-right: 8px;
  }

  .mobile-batch-bar {
    padding: 10px 14px;
  }

  .mobile-batch-bar .el-tag {
    font-size: 13px;
  }

  .action-btn {
    width: 28px;
    height: 28px;
    font-size: 14px;
  }
}

@media (max-width: 480px) {
  .app-title {
    font-size: 18px;
  }

  .app-icon {
    font-size: 18px;
    margin-right: 6px;
  }

  .app-main {
    padding: 12px;
  }

  .action-bar {
    gap: 10px;
  }

  .buttons .el-button {
    padding: 8px 12px;
    font-size: 12px;
  }

  .mobile-batch-bar {
    padding: 8px 12px;
  }

  .mobile-batch-bar .el-tag {
    font-size: 12px;
  }

  .breadcrumb {
    font-size: 12px;
    padding: 6px 10px;
  }

  .file-table :deep(.el-table__body tr td) {
    padding: 8px 0;
    font-size: 12px;
  }

  .file-icon {
    font-size: 15px;
    margin-right: 6px;
  }

  .file-name {
    font-size: 12px;
  }

  .action-btn {
    width: 26px;
    height: 26px;
    font-size: 13px;
  }

  .el-button-group .el-button {
    padding: 6px;
  }
}
</style>
